package org.bigk.invoices.actions.invoices;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.bigk.invoices.Globals;
import org.bigk.invoices.actions.AbstractCRUDAction;
import org.bigk.invoices.exceptions.ServiceException;
import org.bigk.invoices.model.Invoice;
import org.bigk.invoices.model.InvoiceFilter;
import org.bigk.invoices.model.InvoicePosition;
import org.bigk.invoices.model.PaymentKind;
import org.bigk.invoices.services.InvoicesService;
import org.bigk.invoices.services.PaymentKindsService;
import org.bigk.invoices.utils.DisplayTagUtils;

import com.opensymphony.xwork2.ActionContext;

public class InvoicesAction extends AbstractCRUDAction<Invoice> {
	
	/**
	 * Logger for this class
	 */
	private static final Log logger = LogFactory.getLog(InvoicesAction.class);
	private static final long serialVersionUID = 3190832719110023997L;
	
	public static final String REDIRECT_CREATE_EDIT_REFRESH = "redirectCreateEditRefresh";
	public static final String REDIRECT_CREATE_INVOICE_POSITION = "createInvoicePosition";
	
	private Long id;
	private Long pId;
	private InvoiceFilter filter;
	
	private InvoicesService invoicesService;
	private PaymentKindsService paymentKindsService;
	
	private List<PaymentKind> paymentKindsList;

	@Override
	public void prepare() throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("prepare() - start");
		}

		this.paymentKindsList = this.paymentKindsService.listAllItems();

		if (logger.isDebugEnabled()) {
			logger.debug("prepare() - end");
		}
	}
	
	@Override
	public void prepareList() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("prepareList() - start");
			logger.debug("prepareList() - this.filter=" + this.filter);
		}
		
		if (this.filter == null)
			this.filter = new InvoiceFilter();
		
		this.filter.setCurrentPage(DisplayTagUtils.getCurrentPage4Id("rs"));
		
		list = invoicesService.listItems4Page(this.filter);

		if (logger.isDebugEnabled()) {
			logger.debug("prepareList() - filter=" + filter);
			logger.debug("prepareList() - end");
		}
	}

	@Override
	public void prepareCreate() throws ServiceException {
		this.model = this.invoicesService.prepareNewInvoice();
		InvoicesActionHelper.storeInvoiceInSession(this.model);
	}

	@Override
	public void prepareSave() throws ServiceException {
		this.model = InvoicesActionHelper.retrieveInvoiceFromSession();
	}

	@Override
	public String save() throws ServiceException {
		invoicesService.saveInvoice(model);
		addActionMessage(getText("msg.recordInsertedSuccess"));
		return REDIRECT_LIST;
	}

	@Override
	public void prepareEdit() throws ServiceException {
		this.model = invoicesService.getInvoice(id);
		InvoicesActionHelper.storeInvoiceInSession(this.model);
	}
	
	@Override
	public void prepareUpdate() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("prepareUpdate() - start");
		}

		this.model = InvoicesActionHelper.retrieveInvoiceFromSession();

		if (logger.isDebugEnabled()) {
			logger.debug("prepareUpdate() - end");
		}
	}
	
	@Override
	public String update() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("update() - start");
		}

		invoicesService.updateInvoice(model);
		addActionMessage(getText("msg.recordUpdatedSuccess"));

		if (logger.isDebugEnabled()) {
			logger.debug("update() - end - return value=" + REDIRECT_LIST);
		}
		return REDIRECT_LIST;
	}

	public void prepareCreateEditRefresh() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("prepareCreateEditRefresh() - start");
		}

		this.model = InvoicesActionHelper.retrieveInvoiceFromSession();

		if (logger.isDebugEnabled()) {
			logger.debug("prepareCreateEditRefresh() - end");
		}
	}

	@SkipValidation
	public String createEditRefresh() throws ServiceException {
		return INPUT;
	}

	@Override
	public void prepareShow() throws ServiceException {
		model = invoicesService.getInvoice(this.getId());
	}
	
	@Override
	public void prepareDelete() throws ServiceException {
		model = invoicesService.getInvoice(id);
	}
	
	@Override
	public String delete() throws ServiceException {
		invoicesService.deleteInvoice(model);
		return REDIRECT_LIST;
	}

	public void prepareCreateInvoicePosition() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("prepareCreateInvoicePosition() - start");
		}

		this.model = InvoicesActionHelper.retrieveInvoiceFromSession();
		
		if (logger.isDebugEnabled()) {
			logger.debug("prepareCreateInvoicePosition() - end");
		}
	}

	@SkipValidation
	public String createInvoicePosition() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("createInvoicePosition() - start");
		}

		InvoicesActionHelper.storeInvoiceInSession(this.model);
		
		// save current invoice's parameters into session
//		Invoice sInvoice = this.retrieveInvoiceFromSession();
//		List<InvoicePosition> sInvoicePositions = sInvoice.getInvoicePositions();
//		sInvoice = this.model;
//		sInvoice.setInvoicePositions(sInvoicePositions);
//		this.storeInvoiceInSession(sInvoice);
		
		if (logger.isDebugEnabled()) {
			logger.debug("createInvoicePosition() - end - return value=" + REDIRECT_CREATE_INVOICE_POSITION);
		}
		return REDIRECT_CREATE_INVOICE_POSITION;
	}

	public void prepareDeleteInvoicePosition() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("prepareDeleteInvoicePosition() - start");
		}

		Map<String, Object> session = ActionContext.getContext().getSession();
		this.model = (Invoice) session.get(Globals.SP_INVOICE);
		
		if (logger.isDebugEnabled()) {
			logger.debug("prepareDeleteInvoicePosition() - end");
		}
	}

	@SkipValidation
	public String deleteInvoicePosition() throws ServiceException {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteInvoicePosition() - start");
		}

		int pid = this.getPId().intValue();

		if (logger.isDebugEnabled()) {
			logger.debug("deleteInvoicePosition() - pid=" + pid);
		}

		List<InvoicePosition> sInvoicePositions = this.model.getInvoicePositions();
		if (logger.isDebugEnabled()) {
			logger.debug("deleteInvoicePosition() - before remove - sInvoicePositions=" + CollectionUtils.size(sInvoicePositions));
		}

		sInvoicePositions.remove(pid);
		if (logger.isDebugEnabled()) {
			logger.debug("deleteInvoicePosition() - after remove - sInvoicePositions=" + CollectionUtils.size(sInvoicePositions));
		}
		
		if (logger.isDebugEnabled()) {
			logger.debug("deleteInvoicePosition() - end - return value=" + REDIRECT_CREATE_EDIT_REFRESH);
		}
		return REDIRECT_CREATE_EDIT_REFRESH;
	}
		
	public InvoicesService getInvoicesService() {
		return invoicesService;
	}

	public void setInvoicesService(InvoicesService invoicesService) {
		this.invoicesService = invoicesService;
	}

	public PaymentKindsService getPaymentKindsService() {
		return paymentKindsService;
	}

	public void setPaymentKindsService(PaymentKindsService paymentKindsService) {
		this.paymentKindsService = paymentKindsService;
	}

	public InvoiceFilter getFilter() {
		return filter;
	}

	public void setFilter(InvoiceFilter filter) {
		this.filter = filter;
	}
	
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getPId() {
		return pId;
	}

	public void setPId(Long id) {
		pId = id;
	}

	public List<PaymentKind> getPaymentKindsList() {
		return paymentKindsList;
	}

	public void setPaymentKindsList(List<PaymentKind> paymentKindsList) {
		this.paymentKindsList = paymentKindsList;
	}
}
